﻿using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace AppEventLib
{
    public class AppEventClient
    {
        string BaseUrl;
        bool _initialized;
        Dictionary<string, List<AppEvent>> procedureStack = new Dictionary<string, List<AppEvent>>();
        public void Init(string baseUrl, string appId, string appName, string appVersion, string channel)
        {
            if (_initialized)
                return;
            AppID = appId;
            BaseUrl = baseUrl;
            AppName = appName;
            AppVersion = AppVersion;
            Channel = channel;
            AppVersion = LoadAppVersion();
            DeviceID = LoadDeviceId();
            DeviceModel = "WIN PC";
            DeviceBrand = "WINDOWS";
            Os = Environment.OSVersion.VersionString;
            _initialized = true;
        }
        public void SetUserID(string userId)
        {
            UserID = userId;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="content"></param>
        public void AddEvent(string name, string content = null)
        {
            AddEvent(null, name, content);
        }
        /// <summary>
        /// 提交事件
        /// </summary>
        /// <param name="procedure">过程名称，用于收集操作历史</param>
        /// <param name="name"></param>
        /// <param name="content"></param>
        public void AddEvent(string procedure, string name, string content)
        {
            if (!_initialized)
                throw new Exception("请先使用AppEventClient.Init方法初始化");
            var model = GetModel();
            model.EventTime = DateTime.Now;
            model.Name = name;
            model.Content = content;
            if (!string.IsNullOrEmpty(procedure))
            {
                lock (procedureStack)
                {
                    if (!procedureStack.ContainsKey(procedure))
                    {
                        procedureStack[procedure] = new List<AppEvent>();
                    }
                    if (procedureStack[procedure].Count > 0)
                    {
                        model.PrevEvent = JsonConvert.SerializeObject(procedureStack[procedure].Last());
                        model.StackTrace = JsonConvert.SerializeObject(procedureStack[procedure]);
                    }
                    procedureStack[procedure].Add(model);
                    if (procedureStack[procedure].Count > 5)
                    {
                        procedureStack[procedure].RemoveAt(0);
                    }
                }
            }
            try
            {
                var flag = false;
                RestSharp.RestClient client = new RestClient(BaseUrl);
                RestRequest request = new RestRequest("api/appEvent/addEvent", Method.POST);
                request.AddHeader("Content-Type", "application/json; charset=utf-8");
                request.RequestFormat = DataFormat.Json;
                request.AddBody(model);
                var response = client.Execute<JsonResp>(request);
                if (response.StatusCode != System.Net.HttpStatusCode.InternalServerError)
                {
                    if (response.Data.code == 200)
                    {
                        flag = true;
                    }
                }
                if (!flag)
                    Debugger.Break();
            }
            catch (Exception ex)
            {
                Debugger.Break();
            }
        }
        private AppEvent GetModel()
        {
            var model = new AppEvent();
            model.AppName = AppName;
            model.AppVersion = AppVersion;
            model.Channel = Channel;
            model.DeviceID = DeviceID;
            model.DeviceModel = DeviceModel;
            model.DeviceBrand = DeviceBrand;
            model.UserID = UserID;
            model.UserSID = UserSID;
            model.Os = Os;
            return model;
        }
        private static string LoadAppVersion()
        {
            var asm = Assembly.GetEntryAssembly();
            if (asm != null) return asm.GetName().Version.ToString();
            else
            {
                return null;
            }
        }
        private static string LoadDeviceId()
        {
            string text = null;
            string path = Path.Combine(StorageHelper.LocalStoragePath(), "DeviceId.js");
            try
            {
                if (StorageHelper.FileExists(path))
                {
                    text = (string)StorageHelper.Load(path, typeof(string));
                }
            }
            catch (Exception arg_32_0)
            {
                //Sdk.LogInternalException(arg_32_0);
            }
            if (text == null)
            {
                try
                {
                    text = Guid.NewGuid().ToString();
                    StorageHelper.Save(text, path);
                }
                catch (Exception arg_5A_0)
                {
                    //Sdk.LogInternalException(arg_5A_0);
                }
            }
            return text;
        }
        public string AppID { get; set; }
        /// <summary>
        /// AppName
        /// </summary>
        public string AppName { get; set; }
        /// <summary>
        /// App版本
        /// </summary>
        public string AppVersion { get; set; }
        /// <summary>
        /// 分发渠道
        /// </summary>
        public string Channel { get; set; }
        /// <summary>
        /// 设备ID
        /// </summary>
        public string DeviceID { get; set; }
        /// <summary>
        /// 用户ID
        /// </summary>
        public string UserID { get; set; }
        /// <summary>
        /// 登录用户具有的会话ID
        /// </summary>
        public string UserSID { get; set; }
        /// <summary>
        /// 操作系统
        /// </summary>
        public string Os { get; set; }
        /// <summary>
        /// 设备商标
        /// </summary>
        public string DeviceBrand { get; set; }
        /// <summary>
        /// 设备型号
        /// </summary>
        public string DeviceModel { get; set; }
    }
}
